package com.lxk.mall.pms.service.impl;

import com.lxk.mall.pms.domain.PmsProductPropertyValue;
import com.lxk.mall.pms.enums.PmsErrorCodeConstants;
import com.lxk.mall.pms.mapper.PmsProductPropertyValueMapper;
import com.lxk.mall.pms.service.IPmsProductPropertyValueService;
import com.lxk.mall.pms.service.IPmsProductSkuService;
import jakarta.annotation.Resource;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.lxk.mall.pms.domain.bo.property.PmsProductPropertyValueBo;
import com.lxk.mall.pms.domain.vo.property.PmsProductPropertyValueVo;

import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.Set;

/**
 * 商品属性值Service业务层处理
 *
 * @author Lion Li
 * @date 2024-06-06
 */
@RequiredArgsConstructor
@Service
public class PmsProductPropertyValueServiceImpl implements IPmsProductPropertyValueService {

    private final PmsProductPropertyValueMapper baseMapper;

    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private IPmsProductSkuService productSkuService;

    /**
     * 查询商品属性值
     *
     * @param id 主键
     * @return 商品属性值
     */
    @Override
    public PmsProductPropertyValueVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询商品属性值列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 商品属性值分页列表
     */
    @Override
    public TableDataInfo<PmsProductPropertyValueVo> queryPageList(PmsProductPropertyValueBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<PmsProductPropertyValue> lqw = buildQueryWrapper(bo);
        lqw.orderByDesc(PmsProductPropertyValue::getId);
        Page<PmsProductPropertyValueVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的商品属性值列表
     *
     * @param bo 查询条件
     * @return 商品属性值列表
     */
    @Override
    public List<PmsProductPropertyValueVo> queryList(PmsProductPropertyValueBo bo) {
        LambdaQueryWrapper<PmsProductPropertyValue> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<PmsProductPropertyValue> buildQueryWrapper(PmsProductPropertyValueBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PmsProductPropertyValue> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getPropertyId() != null, PmsProductPropertyValue::getPropertyId, bo.getPropertyId());
        lqw.like(StringUtils.isNotBlank(bo.getName()), PmsProductPropertyValue::getName, bo.getName());
        lqw.eq(bo.getStatus() != null, PmsProductPropertyValue::getStatus, bo.getStatus());
        return lqw;
    }

    /**
     * 新增商品属性值
     *
     * @param bo 商品属性值
     * @return 是否新增成功
     */
    @Override
    public Long insertByBo(PmsProductPropertyValueBo bo) {
        PmsProductPropertyValue add = MapstructUtils.convert(bo, PmsProductPropertyValue.class);
        // 如果已经添加过该属性值，直接返回
        PmsProductPropertyValue dbValue = baseMapper.selectByName(add.getPropertyId(), add.getName());
        if (dbValue != null) {
            return dbValue.getId();
        }
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            return add.getId();
        }
        return null;
    }

    /**
     * 修改商品属性值
     *
     * @param bo 商品属性值
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(PmsProductPropertyValueBo bo) {
        validatePropertyValueExists(bo.getId());
        // 校验名字唯一
        PmsProductPropertyValue value = baseMapper.selectByName
            (bo.getPropertyId(), bo.getName());
        if (value != null && !value.getId().equals(bo.getId())) {
            throw new ServiceException(PmsErrorCodeConstants.PROPERTY_VALUE_EXISTS);
        }
        PmsProductPropertyValue update = MapstructUtils.convert(bo, PmsProductPropertyValue.class);
        boolean b = baseMapper.updateById(update) > 0;
        if (b) {
            b = productSkuService.updateSkuPropertyValue(update.getId(), update.getName());
        }
        return b;
    }

    /**
     * 验证属性值是否存在。
     * 通过ID查询属性值信息，如果查询结果为空，则抛出服务异常，表示该属性值不存在。
     * 此方法用于在业务操作前验证属性值的有效性，避免无效操作导致的数据错误。
     *
     * @param id 属性值的ID，用于查询属性值信息。
     * @throws ServiceException 如果属性值不存在，则抛出服务异常，携带错误码表示属性值不存在。
     */
    private void validatePropertyValueExists(Long id) {
        if (baseMapper.selectById(id) == null) {
            throw new ServiceException(PmsErrorCodeConstants.PROPERTY_VALUE_NOT_EXISTS);
        }
    }


    /**
     * 校验并批量删除商品属性值信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            for (Long id : ids) {
                if (baseMapper.selectById(id) == null) {
                    throw new ServiceException(PmsErrorCodeConstants.PROPERTY_VALUE_NOT_EXISTS);
                }
            }
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<PmsProductPropertyValue> getPropertyValueListByPropertyId(Set<Long> propertyIds) {
        return baseMapper.selectListByPropertyId(propertyIds);
    }

    @Override
    public int getPropertyValueCountByPropertyId(Long id) {
        return baseMapper.selectCountByPropertyId(id);
    }

    @Override
    public Boolean deletePropertyValueByPropertyIds(Collection<Long> ids) {
        LambdaQueryWrapper<PmsProductPropertyValue> lqw = Wrappers.lambdaQuery();
        lqw.in(PmsProductPropertyValue::getPropertyId, ids);
        return baseMapper.delete(lqw) > 0;
    }
}
